home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / LIB211.ZIP;1 / FIELDS.PRG < prev    next >
Encoding:
Text File  |  1993-11-22  |  34.6 KB  |  867 lines

  1. *-----------------------------------------------------------------------
  2. *-- Program...: FIELDS.PRG
  3. *-- Programmer: Ken Mayer (CIS: 71333,1030)
  4. *-- Date......: 08/31/1993
  5. *-- Notes.....: These field processing routines were deemed as not as
  6. *--             commonly used (at least in my own Applications), and
  7. *--             relegated to a library file. See: README.TXT about how
  8. *--             to use this library file.
  9. *-----------------------------------------------------------------------
  10.  
  11. FUNCTION MemoPagr
  12. *-----------------------------------------------------------------------
  13. *-- Programmer..: Martin Leon (HMAN - ATBBS/Borland BBS)
  14. *-- Date........: 10/28/1991
  15. *-- Notes.......: Used to display a memo on screen, allowing user to
  16. *--               scroll memo at will.
  17. *-- Written for.: dBASE IV, 1.1
  18. *-- Rev. History: 10/28/1991 -- Original
  19. *-- Calls.......: None
  20. *-- Called by...: Any
  21. *-- Usage.......: ?MemoPagr(<cMemo>,<nUlrow>,<nUlcol>, ;
  22. *--                                 <nBrrow>,<nBrcol>)
  23. *-- Example.....: ?MemoPagr(MoreData,10,20,20,65)
  24. *-- Returns.....: .F.
  25. *-- Parameters..: cMemo   = name of memo field
  26. *--               nUlrow  = upper left row position
  27. *--               nUlcol  = upper left column position
  28. *--               nBrrow  = bottom right row position
  29. *--               nBrcol  = bottom right column position
  30. *-----------------------------------------------------------------------
  31.  
  32.    parameters cMemo, nUlrow, nUlcol, nBrrow, nBrcol
  33.    private    cCursor, nEsc, nPgdn, nPgup, nUp, nDn, ;
  34.               nNumlines, nLines, nKey, nAtline, nAtrow 
  35.  
  36.    *-- set environment
  37.    set memowidth to m->nBrcol - m->nUlcol - 1
  38.    m->cCursor = set( "CURSOR" )
  39.    set cursor off
  40.  
  41.    *-- define a few keys
  42.    m->nEsc  = 27
  43.    m->nPgdn = 3
  44.    m->nPgup = 18
  45.    m->nUp   = 5
  46.    m->nDn   = 24
  47.  
  48.    *-- determine size of window
  49.    m->nNumlines = memlines(&cMemo.)
  50.    m->nLines = m->nBrrow - m->nUlrow - 1
  51.    *-- save the screen, so we can restore it
  52.    save screen to sTmp
  53.    @ m->nUlrow+1, m->nUlcol+1 clear to m->nBrrow+1, m->nBrcol+1
  54.    @ m->nUlrow+1, m->nUlcol+1 fill to m->nBrrow+1, m->nBrcol+1 color B/N
  55.    @ m->nUlrow+1, m->nUlcol+1 fill to m->nBrrow-1, m->nBrcol-1 ;
  56.                                                     color RG+/B
  57.    @ m->nUlrow,   m->nUlcol to m->nBrrow, m->nBrcol double color RG+/B
  58.  
  59.    *-- deal with a blank memo ...
  60.    if m->nNumlines = 0
  61.       @ m->nUlrow + 1, m->nUlcol + 1 SAY ;
  62.          "Blank Memo.  Press any key to continue..." color RG+/B
  63.       m->nKey = inkey(0)
  64.       *-- reset the whole thing
  65.       restore screen from sTmp
  66.       release screen sTmp
  67.       set cursor &cCursor.
  68.       RETURN .F.
  69.    endif
  70.  
  71.    m->nAtline = 1
  72.    m->nAtrow = 1
  73.    do while m->nAtline <= m->nNumlines
  74.       *-- Show one window full
  75.       do while m->nAtrow <= m->nLines .and. m->nAtline <= m->nNumlines
  76.          @ m->nUlrow+m->nAtrow, m->nUlcol + 1 SAY ;
  77.             mline( &cMemo., m->nAtline ) color RG+/B
  78.          m->nAtline = m->nAtline + 1
  79.          m->nAtrow = m->nAtrow + 1
  80.       enddo
  81.    
  82.       *-- If at last line of memo...
  83.       if m->nAtline > m->nNumlines
  84.          *-- If memo is shorter than one page, put box character in
  85.          *-- bottom left corner of box, otherwise, put an up arrow
  86.          *-- symbol there.
  87.          @ m->nBrrow - 1, m->nBrcol SAY ;
  88.             iif(m->nNumlines <= m->nLines, chr(186), chr(24)) color W+/B
  89.          do while .T.
  90.             m->nKey = inkey(0)
  91.             *-- If memo is shorter than one page, only allow
  92.             *-- ESC key
  93.             if m->nNumlines <= m->nLines
  94.                if m->nKey = m->nEsc
  95.                   exit
  96.                endif
  97.                *-- Otherwise, allow Esc or PgUp keys
  98.             else
  99.                if m->nKey = m->nEsc ;
  100.                   .or. m->nKey = m->nPgup ;
  101.                   .or. m->nKey = m->nUp 
  102.                   exit
  103.                endif
  104.             endif
  105.             ?? chr(7)
  106.          enddo
  107.          if m->nKey = m->nEsc
  108.             restore screen from sTmp
  109.             release screen sTmp
  110.             set cursor &cCursor.
  111.             RETURN .F.
  112.          endif
  113.          @ m->nUlrow+1, m->nUlcol+1 clear to m->nBrrow-1, m->nBrcol-1
  114.          @ m->nUlrow+1, m->nUlcol+1 fill to m->nBrrow-1, m->nBrcol-1 ;
  115.             color RG+/B
  116.          m->nAtline = m->nAtline -  m->nAtrow - m->nLines + 1
  117.          m->nAtline = iif( m->nAtline < 1, 1, m->nAtline )
  118.          m->nAtrow = 1
  119.          loop
  120.       endif
  121.     
  122.       *-- Not at end of memo yet...
  123.       *-- If on first page, show down arrow only, otherwise show
  124.       *-- up/down arrow on border of box.
  125.       @ m->nBrrow - 1, m->nBrcol say ;
  126.          iif(m->nAtline-m->nLines = 1, chr(25), chr(18)) color W+/B
  127.       do while .T.
  128.          m->nKey = inkey(0)
  129.          *-- If this is the first page of the memo on screen...
  130.          if m->nAtline - m->nLines = 1
  131.             *-- Only honor PgDn, up cursor, and Esc keys
  132.             if m->nKey = m->nPgdn .or. m->nKey = m->nDn ;
  133.                .or. m->nKey = m->nEsc
  134.                exit
  135.             endif
  136.             *-- otherwise honor PgUp and up cursor as well key as well
  137.          else
  138.             if m->nKey = m->nPgup .or. m->nKey = m->nUp ;
  139.                .or. m->nKey = m->nPgdn ;
  140.                .or. m->nKey = m->nDn   ;
  141.                .or. m->nKey = m->nEsc 
  142.                exit
  143.             endif
  144.          endif
  145.          ?? chr(7)
  146.       enddo
  147.       do case
  148.          case m->nKey = m->nEsc
  149.             restore screen from sTmp
  150.             release screen sTmp
  151.             set cursor &cCursor.
  152.             RETURN .F.
  153.          case m->nKey = m->nPgup .or. m->nKey = m->nUp
  154.             @ m->nUlrow+1, m->nUlcol+1 clear to m->nBrrow-1, m->nBrcol-1
  155.             @ m->nUlrow+1, m->nUlcol+1 fill to m->nBrrow-1, m->nBrcol-1;
  156.                                                            color RG+/B
  157.             m->nAtline = (m->nAtline - (2 * m->nLines))
  158.             m->nAtline = iif( m->nAtline < 1, 1, m->nAtline )
  159.             m->nAtrow = 1
  160.             loop
  161.          case m->nKey = m->nPgdn .or. m->nKey = m->nDn
  162.             @ m->nUlrow+1, m->nUlcol+1 clear to m->nBrrow-1, m->nBrcol-1
  163.             @ m->nUlrow+1, m->nUlcol+1 fill to m->nBrrow-1, m->nBrcol-1;
  164.                                                          color RG+/B
  165.             m->nAtrow = 1
  166.             loop
  167.         endcase
  168.      enddo
  169.  
  170. RETURN .F.
  171. *-- EoF: MemoPagr()
  172.  
  173. PROCEDURE ScanMemo
  174. *-----------------------------------------------------------------------
  175. *-- Programmer..: Martin Leon (HMAN)
  176. *-- Date........: 02/27/1992
  177. *-- Notes.......: This simple procedure is used to strip hard carriage
  178. *--               returns out of all Memos in a database.
  179. *-- Written for.: dBASE IV, 1.1
  180. *-- Rev. History: 04/15/1991 - original procedure.
  181. *--               02/07/1992 -- Douglas P. Saine (XRED) modified to
  182. *--               handle passing of database name as a parameter
  183. *-- Calls.......: None
  184. *-- Called by...: Any
  185. *-- Usage.......: Do ScanMemo with "<cDbf>"
  186. *-- Example.....: Do ScanMemo with "TEST"
  187. *-- Returns.....: None.
  188. *-- Parameters..: cDbf = Name of the database to scan memos ...
  189. *-----------------------------------------------------------------------
  190.  
  191.    parameters cDbf
  192.    private    nFields, cFieldname, nLines, nLinenum
  193.  
  194.    use (m->cDbf)
  195.  
  196.    scan   && search database 1 record at a time ...
  197.       m->nFields = 1
  198.       *-- This loop goes through all fields in the database
  199.       do while asc(field(m->nFields)) # 0
  200.          m->cFieldname = field(m->nFields) && save current field name
  201.          if type(m->cFieldname) = "M"     && check to see if it's a memo
  202.             m->nLines = memlines(&cFieldname.)  && # of lines in memo
  203.             if m->nLines > 1               && if there's something there
  204.                delete file temp.txt        && kill old file if it exists
  205.                set printer to file temp.txt 
  206.                                           && copy memo a line at a time
  207.                m->nLinenum = 1              && to temp file, using ???
  208.                do while m->nLinenum <= m->nLines  && command.
  209.                   ??? mline(&cFieldname.,m->nLinenum)
  210.                   ??? " "
  211.                   m->nLinenum = m->nLinenum + 1
  212.                enddo
  213.                close printer
  214.                set printer to
  215.                append memo &cFieldname. from temp.txt overwrite
  216.             endif  && m->nLines > 1
  217.          endif  && type(m->cFieldname) = "M"
  218.          m->nFields = m->nFields + 1  && go to next field ...
  219.       enddo  && asc(field....
  220.    endscan  && scan of database record by record ...
  221.  
  222.    use  && close database
  223.  
  224. RETURN
  225. *-- EoP: ScanMemo
  226.  
  227. PROCEDURE Cut
  228. *-----------------------------------------------------------------------
  229. *-- Programmer..: Michael B. Carlisle (Borland)
  230. *-- Date........: 01/01/1992
  231. *-- Notes.......: This retrieves information from the field the user
  232. *--               has currently selected and stores the information
  233. *--               into a memory variable titled CLIPBOARD. The field
  234. *--               itself is then cleared. CLIPBOARD should be declared
  235. *--               public.
  236. *--               This routine is taken from TECHNOTES.
  237. *-- Written for.: dBASE IV, 1.1
  238. *-- Rev. History: 01/01/1992 -- Original
  239. *-- Calls.......: None
  240. *-- Called by...: Any
  241. *-- Usage.......: do CUT with "<cFld>","<cScrtype>"
  242. *-- Example.....: on key label F6 do CUT with varread(),"READ"
  243. *-- Returns.....: None
  244. *-- Parameters..: cFld     = Field to 'CUT' the data from.
  245. *--               cScrtype = What screen type? Valid options are
  246. *--                          BROWSE, EDIT and READ.
  247. *-----------------------------------------------------------------------
  248.  
  249.    parameters cFld,cScrtype
  250.  
  251.    *-- test field type, ignore if field is memo
  252.    clipboard = iif(type(m->cFld) = "D",;
  253.       right(dtos(&cFld.),4)+substr(dtos(&cFld.),3,2),;
  254.       iif(type(m->cFld) = "L",iif(&cFld.,"T","F"),;
  255.       iif(type(m->cFld)="M","",&cFld.)))
  256.    
  257.    *-- if field type is Numeric or Float, convert to string.
  258.    if type(m->cFld) $ "NF"
  259.       clipboard = ltrim(str(int(fixed(&cFld.)),20)+;
  260.          right(str(fixed(&cFld.) - int(fixed(&cFld.)),20,18,19))
  261.       do while val(right(clipboard,1)) = 0 ;
  262.             .and. .not. right(clipboard,1) = "."
  263.          clipboard = LEFT(clipboard,LEN(clipboard)-1)
  264.       enddo
  265.    endif
  266.  
  267.    *-- Ring bell if field is MEMO, otherwise, clear the field
  268.    if type(m->cFld) = "M"
  269.       ?? chr(7)
  270.    else
  271.       *-- do to difference in function of the HOME keys in BROWSE mode,
  272.       *-- Ctrl-Home has to be used in BROWSE
  273.       if upper(m->cScrtype) = "BROWS"
  274.          keyboard chr(29)+chr(25)  && go to beginning of field and clear
  275.       else
  276.          keyboard chr(26)+chr(25)  && ditto
  277.       endif
  278.    endif
  279.  
  280. RETURN
  281. *-- EoP: Cut
  282.  
  283. PROCEDURE COPY
  284. *-----------------------------------------------------------------------
  285. *-- Programmer..: Michael B. Carlisle (Borland)
  286. *-- Date........: 01/01/1992
  287. *-- Notes.......: This retrieves information from the field the user
  288. *--               has currently selected and stores the information
  289. *--               into a memory variable titled CLIPBOARD. The field
  290. *--               itself is left 'as is' (unlike CUT). CLIPBOARD
  291. *--               should be declared public. This routine is taken
  292. *--               from TECHNOTES.
  293. *-- Written for.: dBASE IV, 1.1
  294. *-- Rev. History: 01/01/1992 -- Original
  295. *-- Calls.......: None
  296. *-- Called by...: Any
  297. *-- Usage.......: do COPY with "<cFld>"
  298. *-- Example.....: on key label F8 do COPY with varread()
  299. *-- Returns.....: None
  300. *-- Parameters..: cFld     = Field to 'COPY' the data from.
  301. *-----------------------------------------------------------------------
  302.  
  303.    parameters cFld
  304.  
  305.    *-- test field type, ignore if field is memo
  306.    clipboard = iif(type(m->cFld) = "D",;
  307.       right(dtos(&cFld.),4)+substr(dtos(&cFld.),3,2),;
  308.       iif(type(m->cFld.) = "L",iif(&cFld.,"T","F"),;
  309.       iif(type(m->cFld.)="M","",&cFld.))
  310.    
  311.    *-- if field type is Numeric or Float, convert to string.
  312.    if type(m->cFld) $ "NF"
  313.       clipboard = ltrim(str(int(fixed(&cFld.),20) + ;
  314.          right(str(fixed(&cFld. - int(fixed(&cFld.),20,18,19))
  315.       do while val(right(clipboard,1)) = 0 ;
  316.             .and. .not. right(clipboard,1)="."
  317.          clipboard = left(clipboard,len(clipboard)-1)
  318.       enddo
  319.    endif
  320.  
  321.    *-- Ring bell if field is MEMO, otherwise, clear the field
  322.    if type(m->cFld) = "M"
  323.       ?? chr(7)
  324.    endif
  325.  
  326. RETURN
  327. *-- EoP: Copy
  328.  
  329. PROCEDURE Paste
  330. *-----------------------------------------------------------------------
  331. *-- Programmer..: Michael B. Carlisle (Borland)
  332. *-- Date........: 01/01/1992
  333. *-- Notes.......: Paste writes out the contents of the CLIPBOARD
  334. *--               (public) memvar to the currently selected field.
  335. *--               Because all values are converted to strings when
  336. *--               stored into the CLIPBOARD, Paste is able to write
  337. *--               values from one field type to another (such as
  338. *--               numeric to character, date to numeric, etc.). This
  339. *--               routine is taken from TECHNOTES.
  340. *-- Written for.: dBASE IV, 1.1
  341. *-- Rev. History: 01/01/1992 -- Original
  342. *-- Calls.......: None
  343. *-- Called by...: Any
  344. *-- Usage.......: do PASTE with "<cFld>","<cScrtype>"
  345. *-- Example.....: on key label F7 do PASTE with varread(), "READ"
  346. *-- Returns.....: None
  347. *-- Parameters..: cFld     = Field to 'PASTE' data in CLIPBOARD to.
  348. *--               cScrtype = What screen type? Valid options are
  349. *--                          BROWSE, EDIT and READ.
  350. *-----------------------------------------------------------------------
  351.  
  352.    parameters cFld, cScrtype
  353.  
  354.    *-- ring bell if field is MEMO, otherwise, fill the field.
  355.    if type(m->cFld) = "M"
  356.       ?? chr(7)
  357.    else
  358.       *-- due to difference in function of HOME in the BROWSE mode,
  359.       *-- Ctrl-Home has to be used in BROWSE.
  360.       if upper(m->cScrtype) = "BROWSE"
  361.          keyboard chr(29)+chr(25)+ClipBoard && go to beginning of field,
  362.                                             && and clear, putting cont-
  363.                                             && tents of clipboard in.
  364.       else
  365.          keyboard chr(26)+chr(25)+ClipBoard
  366.       endif
  367.    endif  && type ...
  368.  
  369. RETURN
  370. *-- EoP: Paste
  371.  
  372. FUNCTION Blanker
  373. *-----------------------------------------------------------------------
  374. *-- Programmer..: Curt Schroeders (Borland Tech Support)
  375. *-- Date........: 07/01/1992
  376. *-- Notes.......: used to BLANK a numeric field once the user presses
  377. *--               a key that may be used IN a numeric field. SIDE
  378. *--               EFFECT -- if you use this function, the original
  379. *--               value in the field will be erased ... this does not
  380. *--               allow editing of the numeric field.
  381. *-- Written for.: dBASE IV, 1.5 (should work in 1.1)
  382. *-- Rev. History: 07/01/1992 -- Original
  383. *--               07/13/1992 -- Ken Mayer - added '-' and '.' as valid
  384. *--               characters in list ...
  385. *-- Usage.......: Blanker()
  386. *-- Example.....: @5,10 get Salary when blanker()
  387. *-- Returns.....: Logical
  388. *-- Parameters..: None
  389. *-----------------------------------------------------------------------
  390.  
  391.    private nX
  392.  
  393.    *-- get keystroke from user
  394.    m->nX = inkey(0)
  395.  
  396.    *-- if nX is in list
  397.    if chr(m->nX) $ "0123456789-."
  398.       keyboard "{CTRL-Y}"  && blank out field
  399.    endif
  400.    keyboard chr(m->nX)        && return this character ...
  401.  
  402. RETURN .T.
  403. *-- EoF: Blanker()
  404.  
  405. FUNCTION GetRange
  406. *-----------------------------------------------------------------------
  407. *-- Programmer..: Joey D. Carroll  (JOEY)
  408. *-- Date........: 10/12/1992
  409. *-- Notes.......: A function to get a range for use with 'set key to
  410. *--               range x,y' or 'set filter to'. Works with character,
  411. *--               numeric, float, and date types.
  412. *-- Written for.: dBASE IV, 1.5
  413. *-- Rev. History: 11/08/1992 Changed to protect active windows.
  414. *--               Added SHADOW  (JOEY)
  415. *--               11/09/1992 Added (optional) cStyle parameter  (JOEY)
  416. *-- Calls.......: CENTER               Procedure in PROC.PRG
  417. *--               SHADOW               Procedure in PROC.PRG
  418. *-- Called by...: Any
  419. *-- Usage.......: ?? GetRange(<cText>,<xPara1>,<xPara2>,<cPicture>, ;
  420. *--                           <nStartrow>,<cColor>[,cStyle])
  421. *-- Example.....: * get a range for a date, dbf in use is ordered by
  422. *--                 TRANDATE
  423. *--               dDate1={}
  424. *--               dDate2={}
  425. *--               ?? GetRange("Enter date range for your report", ;
  426. *--                            dDate1,dDate2,"",10,"w+/r,n/w,w+/gb")
  427. *--               * now use values determined by getrange()
  428. *--               set key to range dDate1,dDate2
  429. *--               go top
  430. *--               * if the dbf is not indexed on a date or if you
  431. *--               *  just =have= to use a filter e.g.--
  432. *--               * set filter to Transdate >= dDate1 .and. ;
  433. *--                               Transdate <= dDate2
  434. *--               report form <yourreport> to print
  435. *-- Returns.....: .t. if correct type parameters, otherwise .f.
  436. *-- Parameters..: cText = Message to center in window.  May be nul "".
  437. *--               xPara1  = First elemement of the 'key'.
  438. *--                         The 'width' of the character 'get' is
  439. *--                         determined by len(xPara1).
  440. *--                         The 'width' of the date 'get' is
  441. *--                         determined by set("century").
  442. *--               xPara2  = Second element of the 'key'.
  443. *--               cPicture = used to determine 'width' and format of
  444. *--                          numeric or float 'get', and the format
  445. *--                          of the character 'get'.  May be nul "".
  446. *--                          Ignored if xPara1 is date type.
  447. *--               nStartrow = Row to place top of window.
  448. *--                           Message row (24) is protected.
  449. *--               cColor    = Colors to be used ("Normal/HiLite/Box")
  450. *--                           (may be nul "", in order to use the
  451. *--                           default colors of window/screen)
  452. *--               cStyle    = "H" = horizontal  "V" = verticle (may be
  453. *--                           omitted or ""/nul to default to "H" --
  454. *--                           =Very= long parameters default to "V")
  455. *-----------------------------------------------------------------------
  456.  
  457.    parameters cText,xPara1,xPara2,cPicture,nStartrow,cColor,cStyle 
  458.    private cTalk,cColor2,nSaylen,nPictlen,wPrevwind,nEndrow
  459.  
  460.    *-- is a window active
  461.    wPrevwind = window()
  462.    activate screen
  463.  
  464.    *-- in case no color is passed, this will prevent bomb
  465.    m->cColor2 = iif(isblank(m->cColor),"","color &cColor.")
  466.  
  467.    *-- calculate window size based on parameters
  468.    do case
  469.       case type("m->xPara1") = "C"
  470.          *-- xPara1,xPara2 should initialized with
  471.          *--  space(len(alias->fieldname))
  472.          *--  or space(len(var))
  473.          m->nPictlen = 2 * len(m->xPara1)
  474.       case type("m->xPara1") = "N" .or. type("m->xPara1") = "F"
  475.          *-- gotta have a picture to define window width
  476.          m->cPicture = iif(isblank(m->cPicture),"9999999999",;
  477.                                                 m->cPicture)
  478.          m->nPictlen  = 2 * len(m->cPicture)
  479.       case type("m->xPara1")="D"
  480.          m->nPictlen = 2 * (iif(set("CENTURY")="OFF",8,10))
  481.       otherwise
  482.          if .not. isblank(wPrevwind)
  483.             activate window &wPrevwind.
  484.          endif
  485.          ?? chr(7)
  486.          RETURN .F.                  && stupid!
  487.    endcase
  488.  
  489.    m->cText = " "+m->cText       && don't jamb against box edge
  490.  
  491.    *-- is the window width going to be wider than 75 cols, OR was "V"
  492.    *--   passed in the cStyle param?  If so, use verticle style
  493.  
  494.    m->nSaylen = len("From: ") + len("To: ")
  495.    m->nWindwidth = m->nSaylen + m->nPictlen + 7
  496.    *-- if len(cText) > nWindwidth, fix it
  497.    m->nWindwidth = MAX(m->nWindwidth,len(m->cText) + 3)
  498.  
  499.    if m->nWindwidth <= 76 ;
  500.       .and. (pcount() < 7 .or. upper(m->cStyle) = "H")
  501.       m->cStyle = "H"                        && make it so
  502.       m->nStartrow = MIN(m->nStartrow,16)    && protect row 24 even from
  503.       m->nStartcol = (80-m->nWindwidth) / 2  && shadow center the window
  504.       m->nEndrow = m->nStartrow + 6
  505.    
  506.       define window wGetrange from m->nStartrow,m->nStartcol to ;
  507.                     m->nEndrow, m->nStartcol+m->nWindwidth ;
  508.                     &cColor2. double
  509.    else
  510.       *-- wants verticle style or params are too wide for horizontal
  511.       *--   so do some re-figgering
  512.       m->cStyle = "V"                        && make it so
  513.       m->nStartrow = MIN(m->nStartrow,14)    && protect row 24 even from
  514.       m->nEndrow = m->nStartrow + 8          && shadow
  515.       *-- recalc window width for this style
  516.       m->nSaylen    = len("From: ")
  517.       m->nPictlen   = m->nPictlen / 2       && doubled for horz., so cut
  518.       m->nWindwidth = m->nSaylen + m->nPictlen + 7 && by 1/2
  519.       *-- if len(cText) > nWindwidth, fix it
  520.       m->nWindwidth = MAX(m->nWindwidth,len(m->cText) + 3)
  521.       m->nStartcol  = (80-m->nWindwidth) / 2  && center the window
  522.    
  523.       define window wGetrange from m->nStartrow,m->nStartcol to ;
  524.              m->nEndrow, m->nStartcol+m->nWindwidth &cColor2. double
  525.    endif
  526.  
  527.    save screen to sGetrange
  528.  
  529.    *-- now use what you've done so far
  530.    do shadow with m->nStartrow,m->nStartcol,m->nEndrow,;
  531.                   m->nStartcol+m->nWindwidth
  532.    activate window wGetrange
  533.    do center with 1,m->nWindwidth - 2,"",m->cText
  534.  
  535.    @ 2,0 to 2,m->nWindwidth - 2
  536.    @ 3,2 say 'From:' GET m->xPara1 picture m->cpicture
  537.  
  538.    if m->cStyle = "H"
  539.       @ 3,(m->nWindwidth- 2 ) - (len("To: ")) - (m->nPictlen/2) - 1 ;
  540.          say 'to:' GET m->xPara2 picture m->cpicture
  541.    else
  542.       @ 5,4 say 'To:' GET m->xPara2 picture m->cpicture
  543.    endif
  544.  
  545.    read
  546.  
  547.    *-- clean up your doin's
  548.    deactivate window wGetrange
  549.    restore screen from sGetrange
  550.    release screen sGetrange
  551.    release window wGetrange
  552.  
  553.    if .not. isblank(wPrevwind)
  554.       activate window &wPrevwind.
  555.    endif
  556.  
  557. RETURN .T.
  558. *-- EoF: GetRange()
  559.  
  560. FUNCTION FldWidth
  561. *-----------------------------------------------------------------------
  562. *-- Programmer..: Kenneth Chan [HazMatZak] (CIS: 72662,1305)
  563. *-- Date........: 03/24/1993
  564. *-- Notes.......: Returns the width of a field, without having to read
  565. *--               the .DBF structure into a file and use low-level
  566. *--               functions ...
  567. *-- Written for.: dBASE IV, 1.5
  568. *-- Rev. History: 01/28/1993 -- Original
  569. *--               03/24/1993 -- Lee Hite -- Enhanced to accept a field
  570. *--               name as well as a field number, also added optional
  571. *--               <cAlias> to allow checking a file that is not
  572. *--               currently selected.
  573. *-- Calls.......: None
  574. *-- Called by...: Any
  575. *-- Usage.......: FldWidth(<nField>[,<cAlias>])
  576. *-- Example.....: ?FldWidth(3)           or
  577. *--               ?FldWidth("MyField")   or
  578. *--               ?FldWidth("MyField","MyFile")
  579. *-- Returns.....: Numeric value
  580. *-- Parameters..: nField = field number (or name) in file structure
  581. *--               cAlias = Optional file alias (defaults to current)
  582. *-----------------------------------------------------------------------
  583.  
  584.    parameters nField, cAlias
  585.    private nReturn, cFldtype, cFldname, cDbf
  586.  
  587.    *-- Deal with alias passed as a parameter
  588.    m->cDbf = iif(type("M->CALIAS") = "L",ALIAS(),m->cAlias)
  589.   
  590.    *-- deal with field parameter being numeric or character
  591.    m->cFldname = iif(type("m->nField") = "N", ;
  592.                      field(m->nField,m->cDbf),m->nField)
  593.  
  594.    *-- ready to go ...
  595.    m->cFldtype = type("&cDbf.->&cFldname.")  && get the type ...
  596.    do case
  597.       case m->cFldtype = "L"
  598.          m->nReturn = 1
  599.       case m->cFldtype = "D"
  600.          m->nReturn = 8
  601.       case m->cFldtype = "C"
  602.          m->nReturn = len(&cDbf.->&cFldname.)
  603.       case m->cFldtype $ "NF"
  604.          m->nReturn = len(transform(&cDbf.->&cFldname., "@L"))
  605.       otherwise
  606.          m->nReturn = 0
  607.    endcase
  608.  
  609. RETURN m->nReturn
  610. *-- EoF: FldWidth()
  611.  
  612. FUNCTION FldDec
  613. *-----------------------------------------------------------------------
  614. *-- Programmer..: Kenneth Chan [HazMatZak] (CIS: 72662,1305)
  615. *-- Date........: 01/28/1993
  616. *-- Notes.......: Returns the number of decimal places of a numeric
  617. *--               field.
  618. *-- Written for.: dBASE IV, 1.5
  619. *-- Rev. History: 01/28/1993 -- Original
  620. *-- Calls.......: None
  621. *-- Called by...: Any
  622. *-- Usage.......: FldDec(<nField>)
  623. *-- Example.....: ?FldDec(3)
  624. *-- Returns.....: Numeric value, 0 if non-numeric field type
  625. *-- Parameters..: nField = field number in file structure
  626. *-----------------------------------------------------------------------
  627.  
  628.    parameters nField
  629.    private nReturn, cTemplate, cFldname
  630.  
  631.    m->cFldname = field(m->nField)
  632.    if type(m->cFldname) $ "NF"    && if it's numeric/float type
  633.       m->cTemplate = transform(&cFldname.,"@L")
  634.       m->nReturn = at(".",m->cTemplate)
  635.       if m->nReturn > 0
  636.          m->nReturn = len(m->cTemplate) - m->nReturn
  637.       endif
  638.    else
  639.       m->nReturn = 0
  640.    endif
  641.  
  642. RETURN m->nReturn
  643. *-- EoF: FldDec()
  644.  
  645. PROCEDURE PopMemo
  646. *-----------------------------------------------------------------------
  647. *-- Programmer..: Charles Miedzinski (CIS: 76711,671) Borland
  648. *-- Date........: 06/03/1993
  649. *-- Notes.......: Charles posted this on CIS in the dBASE Forum, and I
  650. *--               cleaned it up a bit. It will bring up a popup with
  651. *--               the contents of a memo in it (which can then be
  652. *--               scanned in a read-only mode).
  653. *-- Written for.: dBASE IV, 1.5+
  654. *-- Rev. History: 05/28/1993 -- Original posting on CIS
  655. *-- Calls.......: None
  656. *-- Called by...: Any
  657. *-- Usage.......: do PopMemo with <nTop>,<nLeft>,<nBottom>,<nRight>, ;
  658. *--                               <cMemoname>
  659. *-- Example.....: on key label F3 do PopMemo with 5,10,20,60, ;
  660. *--               "EmpRecord"
  661. *-- Returns.....: none
  662. *-- Parameters..: nTop      = Top row of popup
  663. *--               nLeft     = Left column of popup
  664. *--               nBottom   = Bottom row of popup
  665. *--               nRight    = Right column
  666. *--               cMemoname = Name of memofield
  667. *-----------------------------------------------------------------------
  668.  
  669.    parameters m->nTop, m->nLeft, m->nBottom, m->nRight, m->cMemoname
  670.  
  671.    *-- NOTE: if you assign this to a function key, comment out this
  672.    *-- trap, and others noted in the routine, and change the function
  673.    *-- key to the appropriate one:
  674.    * on key label f3 ?? chr(7)
  675.  
  676.    *-- if empty memo
  677.    if memlines(&cMemoname.) = 0
  678.       *-- NOTE: if assigned to a function key, uncomment these lines
  679.       *-- and change function key to appropriate one
  680.       * on key label f3 do popmemo with &nTop.,&nLeft., ;
  681.                &nBottom., &nRight.,"&cMemoname."
  682.       RETURN
  683.    endif
  684.  
  685.    *-- define the popup
  686.    define popup pMemo from m->nTop,m->nLeft to m->nBottom,m->nRight;
  687.       message "Press <Esc> to RETURN to main screen"
  688.   
  689.    *-- determine width of memo lines based on coordinates of popup
  690.    m->nMwidth = set("MEMOWIDTH")   && save current, so we can restore it
  691.    set memowidth to (m->nRight - m->nLeft - 2)
  692.                                    && reserve room for border
  693.    m->nCount = 1
  694.    m->nmemlines = memlines(&cMemoname.)
  695.    do while m->nCount < m->nMemlines + 1
  696.       define bar m->nCount OF pMemo ;
  697.              prompt mline(&cMemoname.,m->nCount)
  698.       m->nCount = m->nCount + 1
  699.    enddo
  700.  
  701.    *-- what do we do when user selects a bar? (<Enter>)
  702.    on selection popup pMemo deactivate popup
  703.    activate popup pMemo
  704.  
  705.    *-- once done, let's clean up
  706.    set memowidth to m->nMwidth
  707.    release popup pMemo
  708.    *-- NOTE: if you assigned this to a function key, uncomment the
  709.    *-- following, and change key name.
  710.    * on key label f3 do popmemo with &nTop.,&nLeft.,&nBottom.,;
  711.    *                                 &nRight., "&cMemoname."
  712.  
  713. RETURN
  714. *-- EoP: PopMemo
  715.  
  716. FUNCTION FldName
  717. *-----------------------------------------------------------------------
  718. *-- Programmer..: Bowen Moursund (CIS: 72662,436)
  719. *-- Date........: 07/12/1993
  720. *-- Notes.......: FldName() uses low level file functions to write
  721. *--               directly to a DBF header, changing the name of a
  722. *--               specified field.
  723. *-- Written for.: dBASE IV, version 1.5, 2.0
  724. *-- Rev. History: 07/12/1993 -- Original
  725. *-- Calls.......: None
  726. *-- Called by...: Any
  727. *-- Usage.......: fldname( <cDbf>, <nField>, <cNewname> )
  728. *-- Example.....: cName = fldname( "MYDBF.DBF", 5, "ADDRESS" )
  729. *-- Returns.....: The new field name or a null string ("") on failure.
  730. *-- Parameters..: cDbf    = The DBF name. Drive and path specs are OK.
  731. *--                         The extension is required.
  732. *--               nField  = The field number.
  733. *--               cNewname= The new field name. Leading and trailing
  734. *--                         spaces will be trimmed, the name truncated
  735. *--                         to 10 characters and converted to upper
  736. *--                         case.
  737. *-- WARNINGS....: NO checking for illegal characters in the new field
  738. *--               name is made, so don't use any <g>. Since the DBF
  739. *--               header is directly altered, a backup might be
  740. *--               desirable in the event of failure. If a field used
  741. *--               in an index expression is changed, the index file
  742. *--               should be rebuilt.
  743. *-----------------------------------------------------------------------
  744.  
  745.    parameters m->cDbf, m->nField, m->cNewname
  746.    private m->cDbf, m->nField, m->cNewname, m->nDbf, m->nNewloc, N, ;
  747.            m->lSuccess,m->cRetstr
  748.    m->lSuccess = .T.
  749.    m->cNewname = upper( left( ltrim( rtrim( m->cNewname ) ), 10 ) )
  750.    use ( m->cDbf )
  751.    m->nFields = fldcount()
  752.    use
  753.    m->lSuccess = ( m->nField <= m->nFields .and. m->nField > 0)
  754.    if m->lSuccess
  755.       m->nOffset = ( 32 * m->nField )
  756.       m->nDbf = fopen( m->cDbf, "rw" )
  757.       m->lSuccess = ( m->nDbf > 0 )
  758.       if m->lSuccess
  759.          m->nNewloc = fseek( m->nDbf, m->nOffset )
  760.          m->lSuccess = ( m->nNewloc = m->nOffset )
  761.          if m->lSuccess
  762.             N = 1
  763.             do while N <= 11
  764.                m->nBytes = fwrite( m->nDbf, chr(0), 1 )
  765.                N = N + 1
  766.             enddo
  767.             m->nNewloc = fseek( m->nDbf, m->nOffset )
  768.             m->lSuccess = ( m->nNewloc = m->nOffset )
  769.             if m->lSuccess
  770.                m->nBytes = fwrite( m->nDbf, m->cNewname )
  771.             endif
  772.          endif
  773.       endif
  774.       m->lSuccess = fclose( m->nDbf )
  775.    endif
  776.    m->cRetstr = iif( m->lSuccess, m->cNewname, "" )
  777.   
  778. RETURN m->cRetstr
  779. *-- EoF: FldName()
  780.  
  781. FUNCTION IsMatch
  782. *----------------------------------------------------------------------
  783. *-- Programmers.: Bowen Moursund (CIS: 72662,436) and
  784. *--               Angus Scott-Fleming (CIS: 75500,3223)
  785. *-- Date........: 10/10/1993
  786. *-- Notes.......: Checks for an index key match in the named DBF or
  787. *--               alias. Similar to version 2.0 KEYMATCH(), except that
  788. *--               a match of the current record is ignored. The UDF may
  789. *--               be used in 1 of 2 modes. If the optional parameter
  790. *--               cOrder is passed to the UDF, then a copy of the named
  791. *--               DBF will be opened in an unused work area, and the
  792. *--               check for a key match made on that copy. Do not use
  793. *--               this mode within a dBASE BEGIN/END TRANSACTION, as the
  794. *--               closing of the copy produces an error. If cOrder is
  795. *--               NOT passed to the UDF, it's required that you USE the
  796. *--               DBF twice, once for data entry and once for testing.
  797. *--               The second USE should include the keywords AGAIN
  798. *--               NOUPDATE:
  799. *--               use THEDBF order (cOrder) in select() alias XXX
  800. *--               use THEDBF order (cOrder) in select() alias YYY ;
  801. *--                                                  again noupdate
  802. *--               WARNING: if you use BEGIN/END TRANSACTION, you must open
  803. *--               the testing database before using this function.
  804. *-- Written for.: dBASE IV, 1.5
  805. *-- Rev. History: None
  806. *-- Calls.......: None
  807. *-- Called by...: Any
  808. *-- Usage.......: IsMatch(<cAlias>,<xValue>[,<nRecNo>]) OR
  809. *--             : IsMatch(<cDBF>,<xValue>,<nRecNo>,<cOrder>)
  810. *-- Examples....: use THEDBF
  811. *--               use THEDBF order ID in select() alias DUPECHEK ;
  812. *--                 again noupdate
  813. *--               @5,5 say "ID: " get ID picture "9999";
  814. *--                  valid requ .not.IsMatch("DUPECHEK", ID, recno()) ;
  815. *--                  message "Enter ID" ;
  816. *--                  error chr(7)+"ID must be unique!"
  817. *--
  818. *--               use THEDBF
  819. *--               @5,5 say "ID: " get ID picture "9999" ;
  820. *--                  valid requ .not. IsMatch(dbf(), ID, recno(), "ID")
  821. *--
  822. *--               * editing a record with memvars
  823. *--               use THEDBF
  824. *--               use THEDBF order ID in select() alias DUPECHEK ;
  825. *--                 again noupdate
  826. *--               @5,5 say "ID: " get m->cID picture "9999" ;
  827. *--                  valid required .not. IsMatch("THEDBF", m->cID, 69)
  828. *-- Returns.....: .T./.F.
  829. *-- Parameters..: REQUIRED
  830. *--               cDbOrAlias = Name or alias of DBF to check for match
  831. *--               xValue     = Value (non-memo type) to check for match
  832. *--               OPTIONAL
  833. *--               nRecNo     = The current record number.  Omit or set
  834. *--                            to 0 if appending new records.
  835. *--               cOrder     = Optional parameter. Production MDX Tag
  836. *--                            used to order the DBF if it's not already
  837. *--                            opened. Must allow SEEK on field being
  838. *--                            checked.
  839. *-----------------------------------------------------------------------
  840.  
  841.    parameters cDbOrAlias, xValue, nRecNo, cOrder
  842.    private nPcount, lRetVal
  843.    nPcount = pcount()
  844.    do case
  845.       case m->nPcount = 2  && DBF is already open and ordered; adding
  846.          lRetVal = seek(m->xValue,m->cDbOrAlias)
  847.       case m->nPcount = 3  && if DBF is already open and ordered
  848.           lRetVal = seek(m->xValue,m->cDbOrAlias) .and. ;
  849.                     (recno(m->cDbOrAlias) <> m->nRecno)
  850.       case m->nPcount = 4  && need to open the DUPECHEK DBF
  851.           private nNewArea
  852.           nNewArea = select()
  853.           use (m->cDbOrAlias) order tag cOrder) again in m->nNewArea ;
  854.               noupdate alias DUPECHEK
  855.           lRetVal = seek(m->xValue,"DUPECHEK") .and. ;
  856.                     (recno("DUPECHEK") <> m->nRecno)
  857.           use in m->nNewArea
  858.    endcase
  859.  
  860. RETURN m->lRetVal
  861. *-- EoF: IsMatch()
  862.  
  863. *-----------------------------------------------------------------------
  864. *-- EoP: FIELDS.PRG
  865. *-----------------------------------------------------------------------
  866.  
  867.